/*
包含n个action creator
异步action
同步action
 */
import io from 'socket.io-client';

import {
    reqRegister,
    reqLogin,
    reqUpdateUser,
    reqUser,
    reqUserList,
    reqChatMsgList,
    reqReadMsg
} from '../api/index';
import {
    AUTH_SUCCESS,
    ERROR_MSG,
    RECEIVE_USER,
    RESET_USER,
    RECEIVE_USER_LIST,
    RECEIVE_MSG_LIST,
    RECEIVE_MSG,
    MSG_READ
} from './action-types';

/*
单例对象
1.创建对象之前: 判断对象是否存在,只有不存在,才去创建。
2.创建对象之后: 保存对象
 */
function initIO(dispatch, userid) {
    if (!io.socket) {
        // 连接服务器, 得到代表连接的 socket 对象
        io.socket = io('ws://localhost:4000');
        // 绑定'receiveMessage'的监听, 来接收服务器发送的消息
        io.socket.on('receiveMsg', function (chatMsg) {
            console.log('客户端接收到服务器的消息:', chatMsg);
            //只有当chatMsg与当前用户相关的消息，才去分发同步action保存
            if (userid == chatMsg.from || userid == chatMsg.to) {
                dispatch(receiveMsg(chatMsg, userid));
            }
        });
    }
}

//发送消息的异步action
export const sendMsg = ({from, to, content}) => {
    return dispatch => {
        console.log('客户端向服务器发送消息', {from, to, content});
        //发送消息
        io.socket.emit('sendMsg', {from, to, content});
    }
}

//注册异步action
export const register = (user) => {
    const {username, password, password2, type} = user;
    if (!username) {
        return errorMsg("用户名必须指定！");
    }
    if (password != password2) {
        return errorMsg("两次密码要一致！");
    }
    return async dispatch => {
        //发送注册的异步请求
        const response = await reqRegister({username, password, type});
        const result = response.data;
        if (result.code == 0) { //成功
            getMsgList(dispatch, result.data._id);
            dispatch(authSuccess(result.data));
        } else {//失败
            dispatch(errorMsg(result.msg));
        }
    }
}

//登录异步action
export const login = (user) => {
    const {username, password} = user;
    if (!username) {
        return errorMsg("用户名必须指定！");
    }
    if (!password) {
        return errorMsg("密码必须指定！");
    }
    return async dispatch => {
        //发送登录的异步请求
        const response = await reqLogin(user);
        const result = response.data;
        if (result.code == 0) { //成功
            getMsgList(dispatch, result.data._id);
            dispatch(authSuccess(result.data));
        } else {//失败
            dispatch(errorMsg(result.msg));
        }
    }
}

//授权成功的同步action
export const authSuccess = (user) => ({type: AUTH_SUCCESS, data: user});

//错误信息的同步action
export const errorMsg = (msg) => ({type: ERROR_MSG, data: msg});

//更新用户异步action
export const updateUser = (user) => {
    return async dispatch => {
        const response = await reqUpdateUser(user);
        const result = response.data;
        if (result.code == 0) {//更新成功
            dispatch(receiveUser(result.data));
        } else {//更新失败
            dispatch(resetUser(result.msg));
        }
    }
}

//接收用户的同步action
export const receiveUser = (user) => ({type: RECEIVE_USER, data: user});

//重置用户的同步action
export const resetUser = (msg) => ({type: RESET_USER, data: msg});

//获取用户信息的异步action
export const getUser = () => {
    return async dispatch => {
        //执行异步action
        const response = await reqUser();
        const result = response.data;
        if (result.code == 0) { //成功
            getMsgList(dispatch, result.data._id);
            dispatch(receiveUser(result.data));
        } else {
            dispatch(resetUser(result.msg));
        }
    }
}

//接收用户列表的同步action
export const receiveUserList = (userList) => ({type: RECEIVE_USER_LIST, data: userList});

//获取用户列表的异步action
export const getUserList = (type) => {
    return async dispatch => {
        //执行异步ajax请求
        const response = await reqUserList(type);
        const result = response.data;
        //得到结果后，分发一个同步action
        if (result.code == 0) {
            dispatch(receiveUserList(result.data));
        }
    }
}

//异步获取消息列表数据(一般函数)
async function getMsgList(dispatch, userid) {
    initIO(dispatch, userid); //初始化socketio对象
    const response = await reqChatMsgList();
    const result = response.data;
    if (result.code === 0) {
        const {users, chatMsgs} = result.data;
        //分发同步action
        dispatch(receiveMsgList({users, chatMsgs, userid}));
    }
}

//接收消息列表的同步action
export const receiveMsgList = ({users, chatMsgs, userid}) => ({
    type: RECEIVE_MSG_LIST,
    data: {users, chatMsgs, userid}
});

//接收一个消息的同步action
export const receiveMsg = (chatMsg, userid) => ({type: RECEIVE_MSG, data: {chatMsg, userid}});

//读取消息的异步action
export const readMsg = (from, to) => {
    return async dispatch => {
        const response = await reqReadMsg(from);
        const result = response.data;
        if (result.code == 0) {
            const count = result.data;
            dispatch(msgRead({count, from, to}));
        }
    }
}

//读取某个聊天消息的同步action
export const msgRead = ({count, from, to}) => ({type: MSG_READ, data: {count, from, to}})

